Быстро пробежаться по плану (~1 мин), не зачитывать. Упомянуть, что начнём с инструментов, а основное внимание уделим API и системным вызовам.
Подчеркнуть ключевое отличие: системное ПО работает ближе к «железу» и ОС. Привести примеры: ОС, драйверы, антивирусы, компиляторы, утилиты (git, docker). Спросить, с каким типом программирования студенты уже знакомы.
Упомянуть, что курс охватывает обе основные платформы: Windows (WinAPI) и Linux (POSIX). Лабораторные работы — практическая основа курса.
Не dwell на каждом инструменте — опросить аудиторию, чем пользуются. Подчеркнуть, что GCC и Clang — ключевые для курса. Упомянуть, что Visual Studio удобна для WinAPI, но в Linux не работает.
CMake — основной инструмент для лабораторных. Make упомянуть как legacy, но широко используемый. Спросить, кто уже работал с CMake.
Выделить strace и AddressSanitizer — они будут активно использоваться в курсе. Спросить, кто знаком с GDB. Упомянуть, что AddressSanitizer встроен в GCC/Clang и не требует отдельной установки.
Rust — не замена C/C++, а альтернатива с акцентом на безопасность. Ядро Linux принимает Rust-модули с версии 6.1 (2022). Спросить студентов, кто слышал о Rust. Cargo — аналог CMake + пакетного менеджера в одном инструменте.
GDB — стандартный отладчик в Linux. Флаг -g добавляет отладочную информацию. Показать, что backtrace — первая команда при падении (segfault).
Valgrind замедляет программу в 10-50 раз — использовать на этапе тестирования, не в production. Memcheck — инструмент по умолчанию.
ASan — основной инструмент для обнаружения ошибок памяти в курсе. Флаг -g обязателен для читаемых отчётов. Упомянуть, что ASan и Valgrind дополняют друг друга.
strace — один из самых полезных инструментов системного программиста. Флаг -e фильтрует вызовы. Флаг -p подключается к запущенному процессу.
WinDbg — основной инструмент для отладки драйверов Windows. Упомянуть WinDbg Preview из Microsoft Store — современный интерфейс.
Подчеркнуть, что кроссплатформенность — не панацея: нужно тестировать на каждой платформе. Qt и Boost — наиболее востребованные в индустрии.
Показать, как std::filesystem абстрагирует различия ОС. Обратить внимание на fs::path — он корректно работает с разделителями на разных платформах. Можно предложить студентам скомпилировать и запустить пример.
Ключевой слайд — подчеркнуть разницу между системным и прикладным программированием. Ошибка в системном ПО может крашнуть всю систему (kernel panic, BSOD). Спросить студентов: какие последствия ошибки в веб-приложении vs драйвере?
Важно: многие студенты знают API из веб-контекста (REST API) — здесь API ОС принципиально другой. Подчеркнуть три уровня и переход между ними. Спросить: может ли приложение напрямую обратиться к оборудованию?
Важная диаграмма — пройти по каждому слою сверху вниз. Подчеркнуть границу user mode / kernel mode — приложение не может напрямую выполнять код ядра. libc выступает обёрткой над системными вызовами.
Подчеркнуть: POSIX — это *стандарт*, а Linux — его *реализация* (с расширениями). Программа, написанная на POSIX API, скомпилируется и будет работать на любой POSIX-совместимой ОС. WinAPI *не* является POSIX-совместимым (частично через Cygwin/WSL).
Упомянуть, что WinAPI содержит десятки тысяч функций — невозможно выучить все. Три основные DLL нужно знать наизусть. stdcall — callee очищает стек, в отличие от cdecl. Unicode-версии функций оканчиваются на W (Wide), ANSI — на A.
Показать, что WinMain заменяет main в GUI-программах Windows. HANDLE — это void*, но не стоит разыменовывать напрямую. Венгерская нотация: LP = Long Pointer, H = Handle, W = Wide. MessageBox — простейшая функция для демонстрации.
Подчеркнуть разницу между высокоуровневым (kernel32.dll → ntdll.dll → ядро) и прямым (ntdll.dll → ядро). Прямые вызовы Nt* функций не рекомендуются — они не документированы и могут измениться.
Важно: int 0x80 — устаревший механизм для x86. На x86-64 используется инструкция syscall с номерами через регистр rax. Номера syscalls различаются между архитектурами (x86 vs x86-64 vs ARM). Всегда рекомендовать libc.
Ключевая идея Linux: «всё есть файл» — сокеты, каналы, устройства доступны через те же open/read/write. Обратить внимание на проверку возвращаемых значений (ошибки!). Пример намеренно упрощён — в реальном коде нужна проверка fd >= 0 и обработка ошибок.
Фундаментальное различие философий: WinAPI — ООП-подход с дескрипторами-объектами, Linux — минимализм и «всё есть файл». Спросить студентов: какой подход кажется более последовательным? Упомянуть, что POSIX — стандарт, а Linux — его реализация (с расширениями).
Рекомендовать сохранить эту таблицу как шпаргалку. Обратить внимание на fork+exec vs CreateProcess — в Linux создание процесса разделено на два шага (копирование + замена образа), что даёт большую гибкость. Sleep(ms) vs usleep(мкс) — разница в единицах.
Привести аналогию: прерывание — как звонок телефона во время работы. Аппаратные — кто-то звонит, программные — вы сами набираете номер, исключения — авария. Подчеркнуть, что прерывания — основа многозадачности (timer interrupt).
Уточнить: 0x80 — для 32-битного Linux через int 0x80, на x86-64 системные вызовы идут через syscall и не используют этот вектор. Исключения CPU: 0 — division by zero, 13 — GPF, 14 — page fault. IRQ диапазон может быть перемещён (IRQ remapping в APIC).
Пройти все 6 шагов последовательно. Ключевой момент: шаг 2 (сохранение контекста) — без него прерванный код не сможет продолжить. sysenter/syscall быстрее int 0x80, т.к. не используют IDT и не проверяют сегментные регистры.
Важно: в обработчике сигнала можно вызывать только async-signal-safe функции (printf — НЕ безопасна, использовать write). SIGINT = Ctrl+C. Упомянуть sigaction() как более надёжную альтернативу signal().
Быстрое резюме (~2 мин). Акцент на пунктах 4 и 5 как фундаменте для всего курса. Предсказать, что тема 2 (процессы/потоки) будет опираться на системные вызовы fork/exec и CreateThread.
Рекомендовать студентам ответить дома. Вопросы 3 и 5 — вероятные темы экзаменационных вопросов.
Задание 3 — самое важное, от него зависит понимание материала. Задание 1 — начать на следующем занятии в аудитории. Упомянуть, что задание 4 можно выполнить на примере GetLastError() vs errno/strerror().
Kerrisk (TLPI) — лучшая книга по системному программированию Linux, доступна онлайн. Таненбаум — для теории ОС. man7.org — незаменимый ресурс, научить студентов им пользоваться: man 2 open, man 3 printf.